﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Drawing;

namespace Bakındur
{
    public class AnimatedWindow : Form
    {
        internal struct SizeFormat
        {
            private int _height;
            public int Height
            {
                get
                {
                    return _height;
                }
            }

            private SizeFormat(int height)
            {
                _height = height;
            }

            private static SizeFormat closed = new SizeFormat(0);
            public static SizeFormat Closed
            {
                get
                {
                    return closed;
                }
            }

            private static SizeFormat mini = new SizeFormat(65);
            public static SizeFormat Mini
            {
                get
                {
                    return mini;
                }
            }

            private static SizeFormat full = new SizeFormat(300);
            public static SizeFormat Full
            {
                get
                {
                    return full;
                }
            }

            public static bool operator ==(SizeFormat x, SizeFormat y)
            {
                return x.Height == y.Height;
            }

            public static bool operator !=(SizeFormat x, SizeFormat y)
            {
                return x.Height != y.Height;
            }

            public override string ToString()
            {
                return Height.ToString();
            }

            public override int GetHashCode()
            {
                return base.GetHashCode();
            }

            public override bool Equals(object obj)
            {
                if (obj is SizeFormat)
                    return this == (SizeFormat)obj;
                return false;
            }
        }

        private SizeFormat sizeFormat;
        internal SizeFormat WindowSizeFormat
        {
            get { return sizeFormat; }
            set
            {
                SizeFormat oldFormat = sizeFormat;
                SizeFormat newFormat = value;

                int newHeight = newFormat.Height;
                int oldHeight = oldFormat.Height;

                if (Height != oldHeight)
                    Height = oldHeight;

                if (newFormat == SizeFormat.Mini)
                {
                    SizeGripStyle = SizeGripStyle.Hide;
                    if (!Visible)
                    {
                        Show();
                        Focus();
                    }
                }
                else if (newFormat == SizeFormat.Full)
                {
                    SizeGripStyle = SizeGripStyle.Show;
                    if (!Visible)
                    {
                        Show();
                        Focus();
                    }
                }
                int changeFactor = 0;
                if (oldHeight > newHeight)
                    changeFactor = -10;
                else if (oldHeight < newHeight)
                    changeFactor = 10;

                if (changeFactor != 0)
                    while (Height != newHeight)
                    {
                        int newSize = Height + changeFactor;

                        if ((newHeight > oldHeight && newSize > newHeight) ||
                            (newHeight < oldHeight && newSize < newHeight))
                        {
                            Height = newHeight;
                            break;
                        }
                        Thread.Sleep(6);
                        Height = newSize;
                    }

                if (newFormat == SizeFormat.Closed)
                {
                    Hide();
                }

                sizeFormat = value;
            }
        }

        bool drag = false;
        int difWidth = 0;
        int difHeight = 0;

        public AnimatedWindow()
        {
            SuspendLayout();
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            this.Name = "MainWindow";
            this.ShowInTaskbar = false;
            this.StartPosition = FormStartPosition.WindowsDefaultLocation;
            this.TopMost = true;
            this.MouseDown += new MouseEventHandler(AnimatedWindow_MouseDown);
            this.MouseMove += new MouseEventHandler(AnimatedWindow_MouseMove);
            this.MouseUp += new MouseEventHandler(AnimatedWindow_MouseUp);
            this.DoubleBuffered = true;
            ResumeLayout();

            SetStyle(ControlStyles.SupportsTransparentBackColor, true);

            WindowSizeFormat = SizeFormat.Closed;
        }

        void AnimatedWindow_MouseUp(object sender, MouseEventArgs e)
        {
            Cursor = Cursors.Default;
            drag = false;
        }

        void AnimatedWindow_MouseMove(object sender, MouseEventArgs e)
        {
            if (drag && e.Button == MouseButtons.Left)
            {
                this.DesktopLocation = new System.Drawing.Point(MousePosition.X - difWidth, MousePosition.Y - difHeight);
            }
        }

        void AnimatedWindow_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                drag = true;
                difWidth = MousePosition.X - this.DesktopLocation.X;
                difHeight = MousePosition.Y - this.DesktopLocation.Y;
                Cursor = Cursors.Hand;
            }
        }
    }
}
